Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cache-element

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cache-element

Memoize a bel element

  • 2.0.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
8
decreased by-52.94%
Maintainers
1
Weekly downloads
 
Created
Source

cache-element stability

npm version build status test coverage downloads js-standard-style

Cache a bel element. Makes rendering elements very fast™. Analogous to React's .shouldComponentUpdate() method, but only using native DOM methods.

Features

  • makes rendering elements very fast™
  • widget API helps with creating stateful wrappers around 3rd party libs
  • implemented in only a couple of lines
  • only uses native DOM methods

Usage

Caching

Here we take a regular element, and cache it so re-renders are fast. We compare the arguments on each run passing it to the compare function:

var cache = require('cache-element')
var html = require('bel')

var element = Element()

let el = element('Tubi', 12) // creates new element
let el = element('Tubi', 12) // returns cached element (proxy)
let el = element('Babs', 12) // creates new element

function Element () {
  return cache(function (name, age) {
    return html`
      <section>
        <p>The person's name is ${name}</p>
        <p>The person's age is ${age}</p>
      </section>
    `
  })
}

Widget

Here we take a widget (e.g. d3, gmaps) and wrap it so it return a DOM node once, and then only has to worry about managing its lifecycle:

var widget = require('cache-element/widget')
var morph = require('nanomorph')
var html = require('bel')

var element = Element()

var el = element('Tubi', 12) // creates new element
var el = element('Tubi', 12) // returns cached element (proxy)
var el = element('Babs', 25) // returns cached element (proxy)

function Element () {
  return widget({
    onupdate: function (el, name, age) {
      var newEl = html`<p>Name is ${name} and age is ${age}</p>`
      morph(el, newEl)
    },
    render: function (name, age) {
      return html`<p>Name is ${name} and age is ${age}</p>`
    }
  })
}

API

createEl = cache(render(...args), compare?)

Cache an element. The compare function is optional, and defaults to:

function compare (args1, args2) {
  var length = args1.length
  if (length !== args2.length) return false
  for (var i = 0; i < length; i++) {
    if (args1[i] !== args2[i]) return false
  }
  return true
}

createEl = widget(methods)

Render a widget. Takes a render function which exposes an update function which takes an onupdate function which is passed arguments whenever arguments are passed into the tree. Unlike cache, widget takes no compare function as it will always return a proxy element. If you want to prevent any updates from happening, run a comparison inside onupdate.

Render a widget. Takes an object with the following methods:

  • render(...args): called to render a node. Expects HTML nodes to be returned
  • onupdate(el, ...args): called when new arguments are passed in. The first argument is the rendered node, any arguments are appended as the arguments
  • onload(el): called when the DOM node is mounted on the DOM tree
  • onunload(el): called when the DOM node is dismounted from the DOM tree. Useful to clean up variables, trigger transitions and the like.

el = createEl(...args)

Render an element, passing it arbitrary arguments. The arguments are passed to the element's compare function (onupdate for widget).

FAQ

Where does this run?

Make sure you're running a diffing engine that checks for .isSameNode(), if it doesn't you'll end up with super weird results because proxy nodes will probably be rendered which is not what should happen. Probably make sure you're using morphdom. Seriously.

What's a proxy node?

It's a node that overloads Node.isSameNode() to compare it to another node. This is needed because a given DOM node can only exist in one DOM tree at the time, so we need a way to reference mounted nodes in the tree without actually using them. Hence the proxy pattern, and the recently added support for it in certain diffing engines:

var html = require('bel')

var el1 = html`<div>pink is the best</div>`
var el2 = html`<div>blue is the best</div>`

// let's proxy el1
var proxy = html`<div></div>`
proxy.isSameNode = function (targetNode) {
  return (targetNode === el1)
}

el1.isSameNode(el1)   // true
el1.isSameNode(el2)   // false
proxy.isSameNode(el1) // true
proxy.isSameNode(el2) // false

How does it work?

Morphdom is a diffing engine that diffs real DOM trees. It runs a series of checks between nodes to see if they should either be replaced, removed, updated or reordered. This is done using a series of property checks on the nodes.

Since v2.1.0 morphdom also runs Node.isSameNode(otherNode). This allows us to override the function and replace it with a custom function that proxies an existing node. Check out the code to see how it works. The result is that if every element in our tree uses cache-element, only elements that have changed will be recomputed and rerendered making things very fast.

What's the exact difference between cache and widget?

  • cache return a proxy node if the arguments were the same. If arguments change, it'll rerender and return a new node.
  • widget will always return a proxy node. It also listens for the node to be unmounted from the DOM so it can clean up internal references, making it more expensive to use.

Installation

$ npm install cache-element

License

MIT

Keywords

FAQs

Package last updated on 04 Jan 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc